#include <stdio.h>
#include <stdlib.h>

// Size of the board (15x15)
#define SIZE 15

// Initialize the game board to all '.'
void initBoard(char board[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; i++)
        for (int j = 0; j < SIZE; j++)
            board[i][j] = '.'; // Empty cell is represented by '.'
}

// Print the current state of the board to the console
void printBoard(char board[SIZE][SIZE]) {
    printf("   ");
    // Print column indices
    for (int i = 0; i < SIZE; i++)
        printf("%2d", i);
    printf("\n");
    // Print each row with its index
    for (int i = 0; i < SIZE; i++) {
        printf("%2d ", i); // Row index
        for (int j = 0; j < SIZE; j++) {
            printf(" %c", board[i][j]); // Print cell content
        }
        printf("\n");
    }
}

/*
 * Check if the player wins after placing a stone at (row, col)
 * Arguments:
 *   board: the game board
 *   row, col: last move's position
 *   ch: the current player's stone ('X' or 'O')
 * Returns:
 *   1 if the player wins, 0 otherwise
 * 
 * Implementation:
 *   - For each of the 4 directions (horizontal, vertical, two diagonals)
 *   - Count consecutive stones of the current player in both directions
 *   - If 5 or more in a line, return win
 */
int checkWin(char board[SIZE][SIZE], int row, int col, char ch) {
    // Directions: right, down, down-right, down-left
    int directions[4][2] = { {0,1}, {1,0}, {1,1}, {1,-1} };
    for (int d = 0; d < 4; d++) {
        int count = 1; // Include the current stone
        // Check in the positive direction
        for (int k = 1; k < 5; k++) {
            int r = row + k * directions[d][0];
            int c = col + k * directions[d][1];
            // Check if within board and same player's stone
            if (r >= 0 && r < SIZE && c >= 0 && c < SIZE && board[r][c] == ch)
                count++;
            else
                break;
        }
        // Check in the negative direction
        for (int k = 1; k < 5; k++) {
            int r = row - k * directions[d][0];
            int c = col - k * directions[d][1];
            // Check if within board and same player's stone
            if (r >= 0 && r < SIZE && c >= 0 && c < SIZE && board[r][c] == ch)
                count++;
            else
                break;
        }
        // If there are 5 or more in a row, the player wins
        if (count >= 5)
            return 1;
    }
    return 0;
}

int main() {
    char board[SIZE][SIZE]; // The chess board
    int row, col, step = 0; // Current move's row/col and step count
    char player[2] = { 'X', 'O' }; // Player symbols
    initBoard(board); // Set up the empty board

    while (1) {
        printBoard(board); // Show board each turn
        printf("Player %d (%c), enter row and column: ", step % 2 + 1, player[step % 2]);
        // Input row and column
        if(scanf("%d %d", &row, &col) != 2) {
            printf("Invalid input. Exiting.\n");
            break;
        }
        // Validate move: inside board and cell is empty
        if (row < 0 || row >= SIZE || col < 0 || col >= SIZE || board[row][col] != '.') {
            printf("Invalid move, try again.\n");
            continue;
        }
        // Place the player's stone
        board[row][col] = player[step % 2];
        // Check if this move wins the game
        if (checkWin(board, row, col, player[step % 2])) {
            printBoard(board);
            printf("Player %d (%c) wins!\n", step % 2 + 1, player[step % 2]);
            break;
        }
        step++; // Next move
        // If all positions are filled, declare a draw
        if (step == SIZE * SIZE) {
            printBoard(board);
            printf("It's a draw!\n");
            break;
        }
    }
    return 0;
}